{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# CRNN 字符识别\n",
    "\n",
    "## CRNN卷积循环网络\n",
    "\n",
    "CRNN是一种的典型的端到端的场景文字识别模型，不同于之前的场景文字识别框架，CRNN将特征提取，序列建模以及转录整合到统一的模型框架中。CRNN拥有如下特性：\n",
    "\n",
    "- 端到端训练，不需要进行单独训练和协调\n",
    "- 处理任意长度的文本，不需要进行字符分割或水平尺度归一化\n",
    "- 无词典和基于词典的识别证明，CRNN不局限于任何预定义的词汇\n",
    "- 模型大小合适，在场景中的效果表现良好\n",
    "\n",
    "在场景文字中，文字以序列的形式出现，识别文字序列需要系统预测一系列对象标签，所以文字识别问题可以看作是序列识别问题。文本的长度也就是序列的长度可能会有很大变化，我们在案例中以CTW街景文字为背景，街道上的广告牌，标语，从简单的单字到复杂的长句可能出现各种不同的文字长度。之前的序列识别中，一种方法为对文字进行分割，将不定长度的序列分割为单字，然后对单字进行识别，这种方法对字符分割的要求更为严格。而另一种方法为将序列识别划分为分类问题，将接近9万个英文单词作为类标签。这种方法可能适合英文字符识别，但是对于汉语中，单字数量多，单词间没有空白的情况显然不能适用。\n",
    "\n",
    "案例中使用的CRNN是一种结合了CNN和RNN的神经网络模型，称为卷积循环神经网络。相比较于传统的神经网络模型，CRNN具有一些优点：\n",
    "\n",
    "- 利用CNN提取特征，更加准确，不需要机器学习中手动提起数据特征\n",
    "- 利用RNN产生一系列标签\n",
    "- 对数据高度进行归一化，但对数据长度没有要求\n",
    "\n",
    "## CRNN 结构\n",
    "\n",
    "![CRNN-pipline](./img/CRNN-2.png)\n",
    "\n",
    "CRNN分为三部分：卷积层，循环层和转录层。 卷积层对图像进行特征提取操作，循环层生成序列标签，转录层将预测变为最终的序列标签。案例中使用了CTC（无词典的转录方式），不会被局限在预定义词汇范围中。\n",
    "\n",
    "![CRNN-structure](./img/CRNN-1.png)\n",
    "\n",
    "## CRNN 评估\n",
    "\n",
    "在四个公共数据集：IIIT5k，SVT， IC03， IC13 上获得的所有识别精度：\n",
    "_“50”，“1k”，“50k”和“Full”表示使用的字典，“None”表示识别没有字典。_\n",
    "![CRNN-evaluation](./img/CRNN-3.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 准备源代码和数据\n",
    "\n",
    "这一步准备案例所需的源代码和数据，相关资源已经保存在OBS中，我们通过ModelArts SDK将资源下载到本地，并解压到当前目录下。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from modelarts.session import Session\n",
    "session = Session()\n",
    "session.download_data(bucket_path=\"modelarts-labs/notebook/DL_sequence_recognition/sequence_recognition.tar.gz\", path=\"./sequence_recognition.tar.gz\")\n",
    "# 使用tar命令解压资源包\n",
    "!tar xvf ./sequence_recognition.tar.gz"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 引入相关的包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install --upgrade opencv-python\n",
    "!pip install keras==2.1.6\n",
    "!pip install tensorflow-gpu==1.8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import keys as keys\n",
    "\n",
    "import os\n",
    "import numpy as np\n",
    "from PIL import Image\n",
    "from keras.layers import Flatten, BatchNormalization, Permute, TimeDistributed, Dense, Bidirectional, GRU\n",
    "from keras.layers import Input, Conv2D, MaxPooling2D, ZeroPadding2D\n",
    "from keras.models import Model\n",
    "from keras import backend as K\n",
    "from keras.layers import Lambda\n",
    "from keras.optimizers import SGD"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 定义模型结构"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def ctc_lambda_func(args):\n",
    "    y_pred, labels, input_length, label_length = args\n",
    "    y_pred = y_pred[:, 2:, :]\n",
    "    return K.ctc_batch_cost(labels, y_pred, input_length, label_length)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_model(height, nclass, learning_rate):\n",
    "    rnnunit = 256\n",
    "    input = Input(shape=(height, None, 1), name='the_input')\n",
    "#     卷积层\n",
    "    m = Conv2D(64, kernel_size=(3, 3), activation='relu', padding='same', name='conv1')(input)\n",
    "    m = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='pool1')(m)\n",
    "    m = Conv2D(128, kernel_size=(3, 3), activation='relu', padding='same', name='conv2')(m)\n",
    "    m = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='pool2')(m)\n",
    "    m = Conv2D(256, kernel_size=(3, 3), activation='relu', padding='same', name='conv3')(m)\n",
    "    m = Conv2D(256, kernel_size=(3, 3), activation='relu', padding='same', name='conv4')(m)\n",
    "\n",
    "    m = ZeroPadding2D(padding=(0, 1))(m)\n",
    "    m = MaxPooling2D(pool_size=(2, 2), strides=(2, 1), padding='valid', name='pool3')(m)\n",
    "\n",
    "    m = Conv2D(512, kernel_size=(3, 3), activation='relu', padding='same', name='conv5')(m)\n",
    "    m = BatchNormalization(axis=1)(m)\n",
    "    m = Conv2D(512, kernel_size=(3, 3), activation='relu', padding='same', name='conv6')(m)\n",
    "    m = BatchNormalization(axis=1)(m)\n",
    "    m = ZeroPadding2D(padding=(0, 1))(m)\n",
    "    m = MaxPooling2D(pool_size=(2, 2), strides=(2, 1), padding='valid', name='pool4')(m)\n",
    "    m = Conv2D(512, kernel_size=(2, 2), activation='relu', padding='valid', name='conv7')(m)\n",
    "\n",
    "    m = Permute((2, 1, 3), name='permute')(m)\n",
    "    m = TimeDistributed(Flatten(), name='timedistrib')(m)\n",
    "#     循环层\n",
    "    m = Bidirectional(GRU(rnnunit, return_sequences=True), name='blstm1')(m)\n",
    "    m = Dense(rnnunit, name='blstm1_out', activation='linear')(m)\n",
    "    m = Bidirectional(GRU(rnnunit, return_sequences=True), name='blstm2')(m)\n",
    "\n",
    "    y_pred = Dense(nclass, name='blstm2_out', activation='softmax')(m)\n",
    "\n",
    "    basemodel = Model(inputs=input, outputs=y_pred)\n",
    "    labels = Input(name='the_labels', shape=[None, ], dtype='float32')\n",
    "    input_length = Input(name='input_length', shape=[1], dtype='int64')\n",
    "    label_length = Input(name='label_length', shape=[1], dtype='int64')\n",
    "#     CTC转录层\n",
    "    loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([y_pred, labels, input_length, label_length])\n",
    "    model = Model(inputs=[input, labels, input_length, label_length], outputs=[loss_out])\n",
    "    sgd = SGD(lr=learning_rate, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5)\n",
    "    model.compile(loss={'ctc': lambda y_true, y_pred: y_pred}, optimizer=sgd)\n",
    "    return model, basemodel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def decode(pred):\n",
    "    charactersS = characters + u' '\n",
    "    t = pred.argmax(axis=2)[0]\n",
    "    length = len(t)\n",
    "    char_list = []\n",
    "    n = len(characters)\n",
    "    for i in range(length):\n",
    "        if t[i] != n and (not (i > 0 and t[i - 1] == t[i])):\n",
    "            char_list.append(charactersS[t[i]])\n",
    "    return u''.join(char_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n",
      "WARNING:tensorflow:From /anaconda3/lib/python3.7/site-packages/keras/backend/tensorflow_backend.py:4249: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use tf.cast instead.\n",
      "WARNING:tensorflow:From /anaconda3/lib/python3.7/site-packages/keras/backend/tensorflow_backend.py:4229: to_int64 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use tf.cast instead.\n"
     ]
    }
   ],
   "source": [
    "characters = keys.alphabet[:]\n",
    "nclass=len(characters)+1\n",
    "height = 32\n",
    "model, basemodel = get_model(height, nclass, learning_rate=0.0001)\n",
    "\n",
    "modelPath = './models/model_crnn.h5'                     \n",
    "basemodel.load_weights(modelPath)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "调用summary函数，可以看到构架出的模型结构："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "the_input (InputLayer)          (None, 32, None, 1)  0                                            \n",
      "__________________________________________________________________________________________________\n",
      "conv1 (Conv2D)                  (None, 32, None, 64) 640         the_input[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "pool1 (MaxPooling2D)            (None, 16, None, 64) 0           conv1[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "conv2 (Conv2D)                  (None, 16, None, 128 73856       pool1[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "pool2 (MaxPooling2D)            (None, 8, None, 128) 0           conv2[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "conv3 (Conv2D)                  (None, 8, None, 256) 295168      pool2[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "conv4 (Conv2D)                  (None, 8, None, 256) 590080      conv3[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "zero_padding2d_1 (ZeroPadding2D (None, 8, None, 256) 0           conv4[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "pool3 (MaxPooling2D)            (None, 4, None, 256) 0           zero_padding2d_1[0][0]           \n",
      "__________________________________________________________________________________________________\n",
      "conv5 (Conv2D)                  (None, 4, None, 512) 1180160     pool3[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "batch_normalization_1 (BatchNor (None, 4, None, 512) 16          conv5[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "conv6 (Conv2D)                  (None, 4, None, 512) 2359808     batch_normalization_1[0][0]      \n",
      "__________________________________________________________________________________________________\n",
      "batch_normalization_2 (BatchNor (None, 4, None, 512) 16          conv6[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "zero_padding2d_2 (ZeroPadding2D (None, 4, None, 512) 0           batch_normalization_2[0][0]      \n",
      "__________________________________________________________________________________________________\n",
      "pool4 (MaxPooling2D)            (None, 2, None, 512) 0           zero_padding2d_2[0][0]           \n",
      "__________________________________________________________________________________________________\n",
      "conv7 (Conv2D)                  (None, 1, None, 512) 1049088     pool4[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "permute (Permute)               (None, None, 1, 512) 0           conv7[0][0]                      \n",
      "__________________________________________________________________________________________________\n",
      "timedistrib (TimeDistributed)   (None, None, 512)    0           permute[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "blstm1 (Bidirectional)          (None, None, 512)    1181184     timedistrib[0][0]                \n",
      "__________________________________________________________________________________________________\n",
      "blstm1_out (Dense)              (None, None, 256)    131328      blstm1[0][0]                     \n",
      "__________________________________________________________________________________________________\n",
      "blstm2 (Bidirectional)          (None, None, 512)    787968      blstm1_out[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "blstm2_out (Dense)              (None, None, 5531)   2837403     blstm2[0][0]                     \n",
      "__________________________________________________________________________________________________\n",
      "the_labels (InputLayer)         (None, None)         0                                            \n",
      "__________________________________________________________________________________________________\n",
      "input_length (InputLayer)       (None, 1)            0                                            \n",
      "__________________________________________________________________________________________________\n",
      "label_length (InputLayer)       (None, 1)            0                                            \n",
      "__________________________________________________________________________________________________\n",
      "ctc (Lambda)                    (None, 1)            0           blstm2_out[0][0]                 \n",
      "                                                                 the_labels[0][0]                 \n",
      "                                                                 input_length[0][0]               \n",
      "                                                                 label_length[0][0]               \n",
      "==================================================================================================\n",
      "Total params: 10,486,715\n",
      "Trainable params: 10,486,699\n",
      "Non-trainable params: 16\n",
      "__________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3. 测试图片尺寸重新调整"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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kIa5DQONGY3dTUlNnccmHmtr9mw++pvdb3taDFsqj2seX32CcqLoxPDJgpODrbmt/afST/W0zWi7dzrx9PUzk890nA07e+Fc0LnT5/3On7zgdaHlosfFY5fcLjVedrnc0O7cfvR359+Pdrh0NFxxvdJ01f1qc+eEzhNdPl2nrgVcO3c99PrlGxE3Om/G3bx9a+qt7tu828/vZN95fTf/7tC9xfcJ90seqD4of6j7sPoflv+o73bpPv4o4FH745jH93q4PS+fiJ987i16Snta/szgWc1zx+ctfUF9V19MedH7MvflUH/xH2p/VL2yeHXkT98/2wcSB3pfi14P/7XyjfabPW/Hv20bjBp8+C7n3dD7kg/aH/Z+dPt4/lPCp2dDsz+TPm/6Yvml+WvY1/vDOcPDuRwRR3YUwGBD09IA+GsPALQkABhX4fmBLr97yQSR3xdlCPwnLL+fycQFgDr4kh652a0AHITNHGLaYgCkR+9YX4A6OY02hYjTnBzlsajwBkP4MDz8Rg8AUjMAX0TDw0Nbhoe/7IJk7wDQOkt+55MKEZ7vt8tidDHnLAY/yD8Bie1tG4ykJf0AAEZTSURBVHic7Z15XJTl+v/fDDPMDDAwDCiSCy6FpoILuWFSqMf0aKEeyTIztVyOLS6nND1JP6njVrlUmmmpmVke+ppkZptaZqS4pJiV5r4RiuwwKzO/P3CZDRhmY+A879erV8793PM8N7Nc83mu+1r8TCaTCQEBAQEBAQEBgQaLqK4XICAgICAgICAg4FkEwScgICAgICAg0MARBJ+AgICAgICAQANHEHwCAgICAgICAg0cQfAJCAgICAgICDRwBMEnICAgICAgINDAEQSfgICAgICAgEADRxB8AgICAgICAgINHEHwCQgICAgICAg0cATBJyAgICAgICDQwBEEn4CAgICAgIBAA0cQfAICAgICAgICDRxB8AkICAgICAgINHAEwScgICAgICAg0MARBJ+AgICAgICAQANHEHwCAgICAgICAg0cQfAJCAgICAgICDRwBMEnICAgICAgINDAEQSfgICAgICAgEADx6uCz3j8E67H/52y4wXevGzdUZhF4ZiZlB+/VtcrERAQELCg7PhBpvXayFfHy+p6Kd6h8Cxvjt3GD8dL6nolAgJ1gp/JZDJ540Kmk1vIf3QmNy8meTGd0JQu3rh0HXGNkuG90J6vfCR6IBXFnDFIgut2VQL1BQPq5dNQn1MhSeiMpGUM4pZN8W8Uhp8rZz3/OfEtkyEpmZ6d2tOmVQytW7agS59E2oSJa3myAo5lXyKkSRNUKgUKmayKidd4d2h/Jhe3YmKn9nRoF0PL6Ba0ursbsdEKF/6a+oiGa9fUKMIUyMS1fL3diPbkL8x64iCaG487/+sBJo9oUWfr8TwlbE75hN2XKh8p+8Xy9Is9aS7YYwGHMHBx/QzO/hVGeGxnlM3uQtG8KcGqsHq1TeodwXdtN/kDJ2C0GhYlL0aZOrxevWCOYUC9/CHKNpy0Go9Eumgtiv5t62RV1WE8+Qn5j76EdMkuFPc1ZMNfXyilZHjnWzcMN/Ebs4nwqd2dP23JfoaG9CTDYjCJHee+YWB07QRIyeE3CYmfajkYN43s/UuJtdB+Jbw7NITJlhdlWvoplo5oU6tr1nf+WP84d4/bCEBcXBJxPe8iptdoXhjbh6rkstvJ+4MXH/yRQqth5eB7mPNSF0K8tQ6vUUHWmx+z9mO11biEpFceYGT/qDpZVXXozmzm+7R5RE3+itiegj2ue0o5PqM7l/MtR0X3r6f/WBfssZfxzi2mvBHiaNBZ/XgZM2aSf+QcoZtmIPGatfM8ppOb7Ig9gFy0swaj7TadkIVPE6D09sqqoDCLokdfAkA7oy/6kctQzhxSeyFe+CvF81ZhDLsDUeNQRMHh+AUH4xccgJ9EAnp9LU+ow1haiqm0FOP1qxjPnUJ03wxChnas7crsYMBYakAU7MYPnkFTeU6lO9wG9l6rSGT973LttBIJlj61JHZc3cXARs6cS2ozNHv6I9xl5yW1njl7x2XmD7zDiYvWb8LbxN76d3b2brKzd0PgYGZ7cxGyYGKaQdYly+HC7QeZebSAf3/Yl+YNyB5rTx6wI/YA9Oye+wW7t7Rl1vxEWim9vbIqKMoiK20eADmrBlKQ/RrdJw6u/Q1B0a8cfmc1+uAoZKpQpIHhiAOD8Q+UIBYHYDToanlCPfryUgzlJWgLr6H56zSSrtPoOsA99lhXZiAgyL32WFdmICDUU/Y4ghYJLtpjL+MdwRfckZAtR1Cveo6yNXssj51fSVHvXwn+YjWyqLrb4nAnfjFjUL4fTMmTM6mwN+HAUor7bUK6ZAOK++raw3GNkvGjLNZp3DyN/H1ZKNamIVU6fibjuR/Q7fnK3Qu0RD4c09COLm1rAhh+SKNwxiYgElF0KAS7sLVYWgIlRRjzcwEI3PoHgc1d/SyHIekZg/b87RsH0ZilBHUIc/G8ViSPpLczYs8OcdMymD+2hyMXZURvd4s9AwXXCkCmQCGX4e7dUoNBg7qkBI1BRqNGzn9WZMpQq5GJ/P7aQ14yxDcIbsb49Mfp+O4XrF1vFU996TT/Scpn4pZhdI3y9+aqPIY0pidp70h5758HuWBvwi8nWDToDEmL/s7IxMbeXp4V1zg2byzlZiOazBfY80cWnV6eR6T1x6cadJf3kPfHdwAUuXeRtwkYhnFAR5d36Ur3vULmqnQgAokqFH+pCyJNW0qFugi9Og+Au+Zn0+oO1+2xsl0bLmeevjUiuf91YmLcbI89jBftTDDyyWuRxK2g8NmlVsf2UDrkISo+/i9BMQ0jqELceThhh5JQr11A2Yotdmbkop3xAPrkVwmZ84jbf6AcR464Zzza84csh89voqTfTgzvbyWos2OKQHRnAiKW2mzduxPRnU1dFnsAooib2yS5GM/nuuGMN0nEv7axcFUgimgC3BZ8kvvau+W8FhRrMTj5VMVd3RgNbLzxuFW7VlXO1Tp5DUcpOfY+qrjJtx7HxcURHh7uhjNf5/rubLJvPU7iUPEuulpovkqxKVaEoZDV7r1PWjSednXy3ZfRfdIImsftYd6ME1bHClg9/GNSPhhBv5iG4epr3LkLc36OIWvdLtau/svODD27Z2Xwy+AuzHjxHhrXoT0OadeJnMyjlsP56RydupuWM/+PmPaO2eOA6F7IePtWnKYnkDW/wy0hWQGq5jf+lYc+P8+uP805EggMdc+bKQ2LBG4LvojuHrDHHsbrH2txwtOEp99FQcoUK2FwEvWjnTG+tQdFQkPZ6glDPn4xskEjKH56FPrztjOMGS+hfmgIis51JXSDkc/cjLjHCopmWAvxXNRP9kL/YjpKRxJsxLhFjFVLbXchvI6nMh7jkbR0/2ckaWAXnL5HFUscnKigW99kyMi49Vji6FOdJDs7u+ZJTmEb4ab5YyOqu8dVPohLYnTPTjRv041JM0ZhExZp9UsWIvPwC1EDUb0SWf5ROPMfy8TytkdN+hMfkrckhZG9lHWzOLcTRPdxD9Jp4FnWPfcdRy7Zzijc/gu7h3RkZOe6ErrBRE/8mNC4lWStetvqWB7nFt9HQcpH9BjsmD32eHy8+5SZh/CUPe6Eqmn9c07VyX2MX+sBqHZuorDfKBvvgvbZREyvfE3I3+t6q9N9+EV1J3TLKXRfLqFk7kpQRWK6sf3n//SmOhR7t5Hc9zThX3SmaMgTNu+JYWEK1395FeX8R6jVJk/0dMK2PI2/wYAzmUF+YjHGAyvIn2wtRN2P/5hXkXVWOWHA8lHPesmjXs2b+Hng2xoiC6riiIH9m5bwyWlo17wZUSoVwWFBSICAgKBKwVZ4AHNZlbE3k8MJevTm+1HokQRKyD5bbDa2kd3fPwONJZTfeL0rQzz16HRllBWUkp9/jl+PFjHohRfoc4cDP75e/OGxvpS+3Oxvy97NxuzdELeIZ2baPlfRqjPJYJU0U7dIW3dg3o5AXh/0Haesju2ekU5ZajLjB9X1Vqf7kEa1YnL6BP7csYsVaadBKUFTWPmutpjYvw7F3m2UPafQv3Un9s+cgHURmaL0x/juxMskzBhJYG1OqnqGe5dMIdBgcMpeicRiNEdXsmeptRB1P4H3v0x0uzCMtdx+EFHA2ffmedSreZM6TLJ3mrpbsrI7yh+2UjRsKHqrzBfd3AcoiT6CokNdCCEN6sVTUP8aiH/H1ohCQiA4wGXPlQkQBbdEkgi6PbmgAvLBjzOUbvzDiTPqMOm0UKLFmHsG4x+/YOr5MmEzBzi9Vr+o3ij376HkhRS0eyzv901fv0TBH2cI2TCHAEfflmBp5VrEYudfv0DLcH9RE8/kEIr7D0XewRlDr6Giw0tojjsy14Duy03oaY6kXRvEjRu7N2nErag58t4slu2uxVM2TiZ+Y83TAKYO6unQPOUjzzgk+OTh0STHxUFcHK0imqOKUhIa2hjp1a1MTjWTV3GjWT69nx0/XTFbx001E2JJLFo3hlBtMUVFRRTmXOLi2T/JLo4nwsopp2jehSTA/KVK3zIDu/sUcuukGR9B2Yrnvx3EqpQdHCm0PJSVlkFQi8cZ6dT3w1X0ZL6WwefHxbTsEEJYiBSJwh9X/aJ6IDAojHsSYG+mHpRAIQRwnW2bnAnxqECvrUBfYqDgajH5JwrRdu/GnBc62CQsOYqocW96vbeT46+P5PIfeRbHjNnz2DvjDF1fmU1EVfds1kgDKn/wxWKnPX8ieYDlKSNqEVRYC8ISkmnuVDiBhrLt87iQ48hcA3m7Pyaf5qjatCY4vDEydyaN+CB1q1GDOxK6bTtFDw62FH3dUgmsE7EHoMawbw/G82B06EfcSW78vYYVLzkdQ2XLn5hwXvABIL4DxdKdiFdNsZNgs5bi+44SlP4+8tYOvD+lrizEPv53Rbr/pAB6NThVGKM2714J2vfS0J6H2zmDkUjmriV0qO+V6pH6QH0OR3c8xdED2Xp0oJ0jPdmbmnErzpBW/Zg4dqydd9oAW6fe3nVOHsNzdufZQRFEU/PHcYu4r009vP0Pbsbkz4awatgXlqKvSyx/qxOxB6Djr6wCCi/BkRMeLGBfWPm/U6t/sfFyOs91tNhmqNcKcRQdXvyGkE3P8Ps3mZbH8j/k8NPZtE1bQ3QLB+yxBwJpg1t6xvNrNHjHHudsW0BOPpy7NRaBatQa7hnge/bYHdR9CTxZW0J3fI0kuvKhX+KrqFaNqd3WoVuR49/OQ6LCw4ju6+amN1SGfPJaQl4Zb+fYIdTf/OmWqzhFrUu7+BIS/Gzsci6ixj7p86H4bF2vADSuvt2acsvHxdoqdn/VDs5zgLhmvunFcwRZFJO3JdO52Y2HCV14Y2VPVHW2oADC29ZtnKOzKPs0d1NNQxnNR73HPU88bufYUc7srTt7bDTUb3tsW1kqD2m4D9zpeogabkMNaLe+i/YvBeI7myMKDfJMUL4kENmYUehf2YQ0pS36A1luOa1JX4bx8mkMZwMInDHGwT13GeL2beFrM7e+KgaRL1pws1IgAEjdaxgD/j6HsEaNKZi88PZgt1SUkxtyhxTvIn5xu48mKSl4/PNs7i2WEB4eQqBcjkwsN0u2ECNW/8wIVeKtbdCktD18M7cXBo35XbYYmfgqi+ObMutWwF8SO69+Sd8w0NjckOtRqzWoi4v563o5zdu7v+yB+zzq9knu1s5DRZQr+D3jJ37+K4A2bZQolFKXtzbtIpbQe3Qzjiy8RL8Rjblw8KxbXjO9XkvJ5eucPuvPoOk9cawKl4Q72gfDTrPyMUo5bil16W5KDRQW3hZAUql73RaqpNncq2rE3qVLbg+2mk2vUYI9dheKlM+Ijfe9QtzuooavnAbdhqXoznsvOVLzbIoHAi5jkE4Zg9hRI2Hxx8aj2LYZqS9u7Wt+Ib93ikcTBvy7PYXq4yYUPjoNo2o8yrfH+IBbuP5imbwSg/R+L28d6LEJAq+KsOjYajN4DZdzLZIPQhorESNGbFOaREHjVnA7w6MpSpkMxGBbxUSGTKYgLKwRd0Q7uNDaECL1eBxLsctuyarQ8/vGE2RdAvfcEtfM9hlfe+Cscrr9sydRjtpji61IBVM/e4S7fdIeX+DlpK9xZ5EnawI7PcX9qVH8lPYCevnj9Pz3497r0NIAsayT24ZmvRrmVu5NarR9tltQ9REX3XOedgm4gMfLoACimCGEfXU3FfI29TIzyXcQ498sEo7f/ElQIJK7/yoGjQZkMvtfbuukAXteYYMBjQFkNdSUUxddsXicsfcYmkmxduPjis2TdMnmaokBFN7/MCUPivP4dqsnS61IHA3Q92nELolugw/bY5fi9RwkoPVg+iy5m3Jpa0IEe+wCYgIbRUDOzYSYYAK88QbWITV+XEwOZbv4Oo76NOob3ott8WvUpo4zfBoCdsIF3I3mMCPk8WRQ2au1VasQFAoFgYGVBRzKc1djnkibsXIqkw7fRXl5OSUlJRSfPcvu7GwgmUPFW60KDFsiD23J6OTRBEYGQnkuxDap4jMipuXA2cxOkiMH1GopjeV19GnydAVoD1PuSfeR1zC4dA/tu3bIe3sfYlXrBtjz2NvIULSOgey8mqc2EGr47gQjf20N/nkBiFs0QRQWYsejJMZPbkA9fyhqix+yGIK/+IgAuQGTCzscfhI5xj8/oNCqFlvAou0E92yMSW3fdPgBJoOaivy/MJzXN6hevTcxFVzxSv03ATfihdiImxqtsldrDZOzd7M6237tFfOvbckfn7Ngw1GiY9oQrgpGFRyMJKgZ01OnWzzn0P79ds/VbNCjPGp+7pP72Q/odDr0ZQX8lZ/DpV+v0m7MMzzUzgfaFfnkr6mMpAV9aJIn5o4WIYSq5HYMuAipzMi+hf9H+k7zd1DOxC3DuFNudMlDJhZL0JzKIvVZy+4c3V8ZwsieIWg19i2SGDDodRTlF3PhQgXRDdAeVxQUcbWuFyFQO+pzzokT1HizJO6c5NAdVeDYSai/TjMbOYnuLMgSXG/UWXHZukVFItJ72yKSATVsOftHtSCggytXP4TuVClSHyiObI0p94JlTFhAVTMFasZ5b6kzRaU9iSf82fknd7NgwTIPnNmSiV1H1UrwaQqukKuWEKKQIZfLkdUQc1BczTEL55/diQYMGnWlJ1QvoekdjbzubWrcuR2OFMK4d0w70nceMxtR89s56NrL9Q3tosvWnVnD6HVvFEEyCKrBTKqiwmnlkj0u4fdTGu72geLI1mhyCy3jzwV77ALO22O7/esFADd6x/1iBhGgSkNnVk9Pt2obxgRXg/xL0W6x6kWbOIQAD37fK/Ksey366G2A1XfCdOkaJrwT19fQ0D75ADqnak/kYsqveZb3kBAJEBdHcqs4IiMDCQwMRC5XIecQqQusejwkjSYtKQa1Oh+1upy8s7lcPpvB7uxIAs0+X5Gt2nll9V3b1qauVwkf/KMpk60clHFxcRaPzZ2cu6fG02lrEly/bnM2C2/o7smEdFpJnMVx8wlJ7CveRQ9fzN4HpDEduFd5jL2Ft8f2vnuMYb164loYoIYjn1nZx4Q2eLLlbkGeZRqf3ld/0q3scdHlEiqgDkuM1V9yFv+dXKfim/Mwqmue9b+KG29QGxE4fTi6uWbi7Hga6oujCGruwmUKj6KzKoAcMLSPB0VNAYZfT9o9YjzzE5oz4B8VgX+IAmQSz4orgx6TQY2xuBhjzmVMoXHIu7WocrrpSM2Fl00aTWXnCweyL0wGDSaDGFEtG8LXT3xNuDmJLJZ3TSbetXesZD+HFmRYZNYmj5zJ3EmxNZ7WW7c8Wn3t9hvtFYeuqY9u9m4H24dkZ1P1mUK8GEHrDAr6PdeEvWlm4uzEMfZd7Ea/5i5IkMJL/GS5m0v35Ds9KGrKuHTc/i948ZlT/HIGGkcFoQyR4y/396zHVV+B1qCjtFhDSU4hGmVTEu4Jr3K65uh1yqg+OsCo1WD0FyN2wB4bDRoMFWICpP8L9lgQbp7ArZ8ccd8x+M/dYnH/pVn3I0GpSU6f05CZYRWnloi0h+vbxFUjsekQcTMGUf/NfyhfY18MegPx3O3Iu91+bMyr3HfyU0UCuRBdtfEBQPMrhb2HVr4/qkhEimbQ2Kq2YnkZptJLmM7n3tqqlKf/SlBr39tCcQVTUXWbe65wCWOJAYJ9zyif3/2J8z1c9ZbZDssP5fNcV9dj7UoOv0tI/GSnn6/11NvoAD7q979FVFIXWqTt4ILZ2LYP/qTfS857a3N+/v1mU4obhNGruyfdnP5QZjly857g8rf7+Hh93amC9i8OIeGe24/Lrld+R2RKCaCHFoHVC2Htr2ROephyAHkEEnlT/EODLHfENGXotZepyM+79TvYMu0wMS0alj02lHgqsfIymjIDBPmePa4L3PsqyDoSOCaekg2Hbg2ZMl5D/VwScqUzJyxF84nldq7fA494dDsXggnedIQgM0eDn6wyMMUvoAlQN4IvYNHXhPRvYzEmvm8GEYdm1OIs+tvxZvm5lUWbrcMj7VBxXQ0NTPD5RcQgSR6P6O52iMPC8Au0DLjxkwSabdHoQQ+marp8mMoLMP71F4YzxR4pteI6Jexeu8xmNGPzDk4/GUtNncAUrWz7xboFl9xkEqIHjiYpBDq1jyGqSSiNQ0IICKh8LwOC4dvkx1ht9oyJi9bxt9bB6HTm2TMBBARcZ2PKZDNBnMyq9NGE63Q38mx0lOQVU1T0FzmXLnI0N8amp67PIWvGg48qWPHx7R9TzfaDZD3Tju5KZ06o4eBmy+1cWb+7PbqdCzKSP3ycB8zssVhWeUFxgAybDileovsryYzvbxl+0DixL6t+7luLs+hvOzPUeejVeTZ95e2hLlBDAxN84rAYVPc8jrxVO4JDwxDLLb9cInEgIjN7bNRX3+XDqC5EnZdD8aUSZA281EptcLvslY6aTOmGCWaB7CdRf/AT8qm9a3+ynEy01tu5D3fzeIyanyzY7jVMOuvYPu8QsGQXIfdVvZXrME5l50UiaeajgUouIIoZQmjqkCqPG498QvHnV5DEdUR8VzT+LZvir7T/uagXFBxggz333u5Z3BlfSPbe+cRW9zbLLfvFSiXuUbVy295GtUDGwJkfYq+D7k1Us99j9YKbMjWZSc+Npavd30oDpcmTzXrpDuWJESPqfVHb2FGdkX38o1kygZotG07R/bk7a3+ynNPstNrO7TWipcdj1PxlMrtxhwad+0v0O8K9i4YzOrGG3RRHcMoeR6CManj2OKD1YO55ZnCVxzW/beboriuExXRA0TIaRdOmBIYGC00Aaon7/ZyN+hCYHElZxu0SLcYN/0E96kvktdyJ1e34xCoDchTyznVXskHccwrS4FLEzZsjigjFTy5HJHH1Nl+Mn7iE8qcHo7XxtkUie38rwZ3dtIUtDkQEGFWRiKLaIgqPgDAZIpnZz5oUDBvWmm2jt0VUBwVyq8Y7bhX9vs8wZBzCYCWSpO8fQeGDGds1cXrn5qq9c9kLiAu5zr6r7+JotMTh3d+wvzDMxSozART89rNLZ6ieaxzcbv5Xtye8yo+y/V669V3wEXEXDw/ex4btt70hhR/vI2vUnXSPqN2p/vzqd6suSM1I7Fx3laAje8QxQKGjSTMlYeEyZPIAZBJX5ac/UrGab5/7gt2XrI9JGPzOP3iws5sElzgQCaCRRyBTxiAJDUcULENitoXlHwBF339o9rrHIPOp7Unv2OOiI1spOniUooOW401nZtGhff2zx3WFBz45YmQTZlOeMc3Cy1f+zjfIUwc4fhrDacpX7LEY8p/+cJ0W3fTvPARFZ3ef9Qql08fbEXvxBKZ/QKA7t1JlbVEeOlXjNH34KYqW3nzty6qd621M5WpqrMXjBvwC7PyQqUYhbVcfjcs1tq9cXcOc1fRsnMvOy5/S946av2WrpyZT0xnrnGvH+Mg862JiVyJ96bfSK/jT48mu/Hf7fgsv36ZVx+n+Ui3qoxiusmN1gcVQi2djqcuuo6rOcQzv7O6zFrLtX1/bEXsKHv3oH9zX2o0CR9qWXut/q3lFytNkbc288cg1e+zuuq1GtXfssb+9FjPyFKLa1Ed7XHd4xCPqFzWQwORIizFTxhRKTzrugjd8/4GVxzsG+ZCOblmfr2A88w0F8Ylo9liVz1cNR7Fzs3vFnsMYMJw5UfM0RwgOcHkL1E9iGVtnyLaxxF4iEcVnaR6OH/UMmtPfMtXM0WVVtcSMDPo1HcDnp+tmq8zd/LF9nUWW7exhCZ7x2Fn1J87YdcCnevv4R3Xg4cGWQkWzPZNtJx1PO7n6/SEspYmcgX9v5pb1+QplZ44zv1c62zOtXhdlE6bueMS9Ys9hDBRdclPcuNT1PtJisWUIRv6JurLHCXR6fR4qIT6vVnjofleM/J8vU54xxWJLVvP0SuTfznAg5uMK5Ys2WYz4PTANqdK9q6w7ClCvnUvZiq9sjvglphK6dEwdejI1GE65qX/T8TQKpme5cFcRiOn8lpqneQHRhGeR1tObycz337vxrzggu7LeXOU/7bCb5Dv/TvqpDEa0qW7rKo6kpHCu26ln5zDh4bB7dzWlT1zhPBvGmTeRSya59x0euVLJuQOW2c91mDlsH38SJnfjv9szLbZkt0/9kd47+lJz+clCvnjD8odd1q8LnZTuXWXdUUbWum9Zu/qazRFZQixz3ujpULFrz6Ch9LKbWn/lLCBz4QEXNmHlVFzdZjFSVzUGJQOeJrJB9JX2Lp7TFY0GEDwhnpI1tzN2yV9JSfpglCltq32q4Yf1FgWcAWRPJdbfgPlbGND9sInSGWl2Xevi6ZsIHd29zv9Op69v0Nt0nTDu+cq92wheqV5vQJ9lGU4g6XOX3Zkmg+FGN3cDJo0aY0k+FRfz8LurBwGNfGD/sGA/by6wjd6Ly67UexM/ymZ68MfcnbzA7OhuUu68l/Tf9zKinX3Rt/zQXp6rrtGug2iOvYs8zvmyLFVx/vN3Mf+LmDaZeE/FuluVrOF6UdXx+Hp93Xj/Ijrw5NhjrFhvdvXC06z99G6eH1H9xuzVPQfIKrQce3B8TAMoKFzB2T0HWD/rGPZucds/25+nR7Wq87/T6esb9Da2V/PHd7jVf+8Vp6eB/N8yLUYi7rFvj40GA8aKSnts0KgxlOVTkpOHtFUPVCofsMd1jEdfAenYuajXDLUwfoaF01HfX10CxwXKZqy1HOr2ah1tb7oP/Q8bKH01jQq7affxyDesIqiDD/QQdQHjqQMe7+1ryit08pkFlC1egF4jQxQaiZ9Cil9AACadDnRa0Goxoansr6UpxHDA8tnaMZ0xdIvHdLUEU0kRNRVq9huzifCp3Z1cq/s4/OECM+9TNnHJownP2HgrgSM3T0+7UfPZuWgf/WaZC8NsUu6+l4xz+3nIbuNTFxqymuGRWnYFPzLVQsDCR5Pur8HYaSg298zVopeuotUA0tetQxcQAOggOI6qcpg15444XwvRRWKfuJc71+/APIr31Bs7ybp/dDUJHNfZMuuc5VCXLtxbJ9ub7uPinn18uOAYFwrtHVWQ8t6D9OtQv11IuvMH3Svu7F2jwLrNnqMUcGr1Qq7rZMiCIxEHBeAvkVKh14Jeh1GnxYiGCh2gK6TorOWzc+Z3p6hVJ/RFpVSoi6ipULPo/vX0H1v39riu8azklXUkeNF4CmeZC7iTlP1rA9IN9luuGba+bfMjIJ8xtM69Xq5RivZ9+2JP9EAqIaljENdvPQuAX3g0foCJSPyiQ/ELboJfeCB+8kD8ZLX/A02afMgvx1j+F6acIkz5uaDRO9c+rvRPtJu3uCRIKw4cqnnSDUThgS5cyU2U7Cdtqrm8iGPW7HEcMBN8N+k7czOrMhsz2UKN9KRZyI33TV1m5Zny0btlw3leuT/RUlRNy+DhdjV8/koussv8RcnYy58lk3DIiRnWjhFjHStm/Nuhww7N8wiyZox5pSWpc8+ZDapZ+/w+Oqy333ItJyOTI1ZjQ6d1on6HTmk4sta+2FP2i2XqSz2J8mF77KgNEyujK6syEIFIFUqANBJRaCCSADn+TgQjV+gKMJaUo9fkoisswqjOA50OI04kA5T9ycXMbegBZyVj+dmjDs+VKX3AHvsAHrfa4v7PIeuwFo15Pb3jaRSn97Dd2tX8Sskr1n1zFxPo2cqeXiCYgAGJaI6bbxPGIHtrFcEJbqiv51Ecv8v1az6E8P0DwYE2Qc5hwOmPrNjDbfCsL9elpRevZp8fl822FD7Jsxgefwc77M5uxKR1+9ih6nnjORM5VPzuLcFTcvY3i3NpykrAIEdjcN7TJxbL0JRra57oMFd4c0RLUi2CApPZk/pQzZ8aCVhquxKXvI+nd23iuwsBRLeIJEwZBIWX2P/dWqZa9TJudUeoC1epPY3792HwxnNsN8/LOnGMdz6Ntt3a1Vxi3ULrvrn3kBRTv717IKPdgDC2nzDPOpYzeMkgHuzlhvp6HiXIYXElumMw/d97wGft8Y1+JF4hrH1LL13Jt/HCbXowwYtWoh1imcBhWDiesvidFi27NG/OtGmLLZ/xUD337t3AqmCZ9P3/Elwf6rl1SEBSm2V6zLiAqx9X6/hCuNGWThGKX7ACv8Ag/OQR+IWdR59h7s2LRDJhHP7BAfhJA0ASgF9A5X9IJIhCA9A++YTlW1xNVw5vYDj/OYmpln685bMfRMa5qmPIwnqwZs8iMhJPcyj/XUvvltVv/KzEpsxy54JdpeAwc+6PZ4FVBsi0jDfo40ikhFWmLYArJTbFpb8yedyCGuf17hbt/EWcQsaDCxLYOdwygePUG1+zs+tj9DPbqj381vcWbdkAUqbF1XPv3g2s7jOS3hnBg53rgWMhqidhtdlp9mF7bM9CiuQRIA/FXxqMRBaEvzQcSfAF8g+ae/MiUA0YQ3CgFJGk0h5LJAGIJBJE4gDEIRJyFk/APNWluq4c/0t4Z18magCKFwdSvNA8KzUXdcp8AvanIRGD6eQGSjdbpp/7Ja8hqLmPbh3VEj/rZIPAevJ3ldY8pV4g60LIhg8w6EMRR0YiCgvDTyau4mbiBIUZg82i1Johf+opAqp5y/ymJ6K7VbswnoA76zIes4T3pyZbDiUt59EeCtDoqW6XslGfmZjsKWMvUevCEYYC9m9dw8SUWbbZvqM/Iu2hNvaeZec8eiLj4kgKr/TwXA9pT/Ynr/D80kN0GpxAu46tuat5a9q0a090o5qFQfRDk5jNAqqVfKM/Ykh0HdiBqA5M/defLHrDPCtVT/pj3xHz4yCai0F7ch+rt1gGRckG96Ff87pOYXAP1u22JIH15O9yp0O8LpF2oducNRQZQlFERCILDUMsFVfhvTzBz2OHmd2QNaXlw08RUc1XRzo0gbxbtQs7ERFdv+Pj3YXXrE1AyitIt31l1SptE0UvdCZ8aU+KH02zekY8Qc8leWdxhhMUPTydiuiO+Ec1QRQS4pYacjfxCwbtUsusT/369ynrosDkpi+wSaeDkmKMuX9hvPQrpo7TCJs5oGF4R92EuENvxz7wmnJLb2D032q+UXat5YRbOf95qlUsHiya9yiu9GvRXLvq0poc5Y9L+TgWOAeg4fMXVCQvs3dsItlrRlUrbi0I68G7Ry1jgo69O5Rx2RnszjZ7MdP2YZrbw4ETRpO8PJkFU+2naCTP/ojlaaPqrJNHqxF/Y8AXm/jGouTmJf4z6xeWv9GKdU8cs3qGgjHPOBan6DKGHFY9upOcFqFENQkiLESKROHvtoRQSRD8/JZlEemsDT8T2DkAvZu+x3ptBfoSLQVXy8i/VIS2QxfmvNChYXhH3URwTG/HSjZryy13/lT9CK7BHhutHHpCC7ZKvHh7GYbizQ/Q93vCMuh0z0yux9vOFr+YhkzppaVpyqk4fxLj+ZMezzK9ifHrpai/9uAFSi84l9wgAAXX7G7/Vk0puu/31DwNMOk83Lnkylc8ZK2A4hYxro9r7fkUbe5n1ap1REW3ILJxI0IDA5FIKg3ITU+oWC7mwGstSVkGEMfoaSPo17sbd7dtSZMQOQa78X56ysvLKbx2lYt/nqd5p5qrwt1GxkNLTVwd/xUvjR7E6lsuviQyzi0n1mU1ZS0Xk9kz2Y6xqoL29/aFG5GPcXFxtIrrS99+DzBg8P20c8BL6FmCGL4siaODdluWJMk8yNReB21m3/mv++iq9NLSNHpyLqnJvaS2Wy7FExTuPMHWnR68QFkhWhAEnzMUXatlrF8peYcza54GVOh9q5OUp/HufoKyN6FvTaHg2ZXVz1NNQVFDrT63Im6AwsjZ8EDNOQzHa55WG0wXd1PycS7yiSOQKGv6yGlQL34CdeFIwuYPr5P3xZh/wUL4+7Vr4qZ1lKLLdDzTt/ac55VBg2y2Nhe9Pc4l7x6ALLoPkyb1qXFecafRwEYgm43Lstm4DEhahXrXpJq9WX2dW1uj2IG8e7SYYYunMGhWNum/Z1RRSqZ26LWWUX1xs5+jTy1qKyq6TkGtnohYLPNsKJWzKO9k6pILzJlxuoZ5bRhfQ60+tyJugMIoyMl6etpzFOS4dynGK99z5ItcWo/8B8rQmu3x+dXjOFP6MH1mDKuT3Hxd4QULwSdqFuWmcqyl5B1zPNO3IeD1988/YQaKCfstCzJbEIn83SleL3Zp4dFRRbpVaPgpwHje9l5VFB1zo6ab6+f2U0VWli25ibOxd3aKddpFcwXtBQnSmJqkhIby/0xAdwB0m19C/PRKFGMG4G/3k1dA2ZwhqL/OBQ5REBmJamrv2v4FLmPMsdy+9GvR1H3b+xaPgtz4DSxg/ePWGapA0iomuOjdc4m42fye4YDYcxkFA2d+iH6G++LUW/W47aEDaNVEWcsziJHJfFHp3UbVqy9Pj71qWZDZAgkpK/o40I3DvVg0K1FK3Pr5kQVD4SVbn5GymRxNqWv1JW+eW6aUoCk0u4azjiSD3jHvljaH3MtiIlvXbI9PrZlC3lnIy5xH6OBlxA4bUEVIeQEnlyRzLjsPOMqP6xuTNNb79lh31bIDSkCTO9y2RWupM9xpj32TOvnzpJM/QLemo/3408RXLTJ3vYKsC8qvfga5Aj+ZDD8PvCq6tSMpXnFb5ErfP4LCA1m6Jo0GU0kJKMKc+1I45O00oE5LpCx/MQGrqvfCGY9sRG1WxNiwYgoFKyKRLlqLor+5F1dD2eRuFnONG56g8I7tNXZmcTcVpyzv+kQtPFWqYQ/606VIO7j+OTj9eRoWncRusGr5KLwXrmzgxM+Wi0hbOp0qmnV4BHd60sSBln6mhC7N3XdyHyJ20j8YsH4939g7mNDTInPXK8haMHfbI1TIZATJJFXcHLrGn+s+4Y3Vt0Vu0juPM9IDWboVGj1lpRoIDqxFgSszxI7Enxk4v6IfJ0r+Q/+Xh1U7X/fbRs6ZFTEu2j6NvdsjiHpqDbH3Wtrjk/N6W8zVfz+Bnxt9Rq/B3rXHZRcs72KlUZ6yx5kUnC8lMqYeVM9wkjoRfKYz31V917JnAkVbtxI6tKM3l4Sokae9INZfd8+kifvJZE4VOa4Nhi/TKPsaYB96w/BqslevUfrCQjvjuegz/8TUv62ZWJQhfXQK6gOW2/2GhYMpbvozIQne8lJdQft/lt5n/2h3+Tf0mKy2Z4zl7vkctHloKfr8aXy5Zj7Js1ZXDk5M54nY2qotDZ/PeYS5vyno2745UcomyEKlSKVSB7bZitm5z3Ikdd062lxo7HBOi1arRVtURFFhDid/O8rlVlP4cumIWnt4NCUlIJG75GGzLssSqnRBuRoMaNRqxAqFzzkRtGd+J6uqg5k/siojmMnJzby5JIIiPH2XYP0uWBcEcw/+MgkhMs8K5uLdr3AiG2AfhYZhVN1B7Bq/v7XEzngeeUdOYbi3rdmrIqPJAxM4t2qNxcyS9GEcbfIDneK9ZY9zuPyj5Q14cFP32WN9oeWIVl035Vs0V89QcOYCBgkYinUEtomlUYsotyebeN32GI9soODJtGqD4vWvDOV6ViqhaWN8M/blfxjTyU8onLvpxqMtaLJeIKAKMabf+ppNT2QYiOKL15HaKWUvvm8GIS/+RfFCy+LbumeHUpa+0yueX9PFfVZrTiQguoY7PsNlB+MeJYgfnYJJJ63sSKKVIrvLff43cVg0D818F/XI0cwet5oHXx7qxFaYnpzfMsjOgGz7Caa1Y+MsHrPjeXSYpJGooXZ/h+Ywj4TE39qMjYtLolWrEBSK2omIkmzLhU+e+gh7m9bmHCWUlBRz9ux1srMrvRTJq7LZOim2VuvwJMVH9pH6z2PVtuA6snAH0w7EMuf/9aSxYI99CsOZzez7IP3Go21cPPo8qirEWOE3r5Nr036sP7GLFxPV2PYbFtJzOvdc/4uD6dssxnPf+gen0r7hzhaet8fGK/vIs1hzAhFNa7bHRQ7FPUpQ9p2AUS+t7EiiC6BpS++Wbyk8tJlf35tHub22cPIEWj6VSky8+5ozePXrq/9yPkVz19Y8ETB9nUbh198TuOENAut5j9kGQ+kvFD76ksWQ7uX/Yvz2ads7kcIs264pxBD0xdtIq4n/DkhZTPCVXyndYF6TMRd1yvNIfnibAA972/XffmE5kDik5mtqyh3M7g5GPn5GlX1W3YUsug9Ld9WcYFEVPhUwH+KckTKXZdnZu8m2KdLnBLszcEW7AqD1nQKwF3d8y3/Szjk0V7PzGKk7L/Hoe4O4r573mG0wlP3CvrR5FkO576Wji59im9RQlEX2pm1Wg21ou/hNohpXfQnV4EV0uPYbx783T+zJ40zqTJQr3iTCwx+F/J+2Ww60G0yjmq6pLbcJF7Nvn4NpnjKdugnU0HBxdQq/Z1aTMKXO5NxbA7l8z3/o9cwwt8SxeknwlaJe/iRlG+wkaqhGoVj7BIZ1z6LOOGl1cA/lY7qhnbCS0MkDhFo6dcLNr84VisekWG18RCJfNsrO+6KhbN4omy+Z+JW3kDuQ7Ceb+hGG37uhOWA++hXFU95DteEpD34OrqD52LK8SsDQnjXHNFrHPara4l/XVTdcQGseMR8XR1x4ONVHzYTA7gyb/rzWxCUnE15cXMOs61y/nn1boJ2tdrJ97HTNEDBHQ+abW9nwsZ1XSdmMqavjufLBN6Rvt3Y7FPDxU5v4aWwCz0zqQIhX1ipgie6GXc3h6NzHKLc4FkHL6Y/ayWDVcOqdsTZe3NAnlhNdjdi7SdOxGyg535sLFt/F7zj86nskLnjKgwlZOVzYZVleJeL+njXbf+u4R3kMQT51FwuF37xsIfYiRq2n3X3dCZQC2gJyfljP8U1rMAL6g//m501NSRrV3eXrelzwma79QsmkFHTn7Rzs9iLKt59CLAZp6pdI4lIpfmWTzbSKNVPIX5OI/P1XCep8h6eXLGCGX+f2iNBQNj3R5j2Uvv8FQXa8rxU/LEFtXZau26uE/N3BrgeEEfz2dgw9zLtdAMcXUrj8bo9l7hqPfGmznSuNd+LzFtUCUb3d+lLwZEY+ww1iwhQKh0Mqrnw1h6aDqusrkczb67Y61uYMMBgMqEtKMIgVjhdPvolEQiQQl5RMXNNIIpo3I0opRVar2FYpRcc3k7r6toxNmpjG0A616X2rQVOkJSf/Enlnc8nOyKBVRN02ca/Iu8AH//yarEt2DnZpz8tv9iZKDHe/NJoWsTt4Y6HtxAvrM5m5/ndS3ulPv85Kj69Z4Dai1u2RoeHkwn7kWoXLNJ2ZQUyM7ResfN9SzvxhNdjqZboktXbwqmG0+/dnFD01DIuaEjlL+Hn93R7L3NX9tt1mO7dprBPlgZTN8alk+aKf+OWWtzWBDotX0dQ8VkIaRtSA6UT1uJ/9Ux+jCNB/8zzn++8i2sWYCg++DAZ0X75J8Vz7Nff8x6xBOTXJwjMSMDQNVdy9FKdMwTY5fg/qJxPRJk4neM6TBNR54dKGimWAsX/rINSrnrARcAFv7UHR2c6vd2EWRTOst+0TUbz+SO08c+K2hG5dSf5Qyx7Mxg1PUNx5DyH3uVv4l1K+xCrB5IFHnNtCruft6MSKsNrV7dMcY56V2EtelM7Dha/w2K3mthkkPrcJ9YeOdZcQi8UowpwM5ZDF8q4b+sMZ/pBaCL6Rz7zAJNerOdcRFfy54wfeSLO/hdTi0T7867l2Ftv5dyUP4o3Y47zzWCanbJ5RQPo/0/k2oS1Pzu7FXRFezuT9n8HydQ1qFsjFTeM4ZyXgIp/dSYf2dr4vRVkcXPWh1WACsc+PrF0tO3Fbus1fxq450yx2bvTfT+Bwu5107enuOo2lnPnQKsEk7uGat3Pt4WPt6IoPf34rZbPpnGWWYs+c0C50S/sP36X+G8jj/A9/EJ3iWjKrR3bHjBd/onhMuyrFnnTJ14RZib1bC2o9AOWhnwkck2j/3HuWUjywI4XLt2BwsWaSgC2mK79abNsalo6izKpmonju14Qk2BNcBZQ8Z7uVG/DWIqROCCe/5gMIXTLeZlw34ynU1+w8wQUqMlejsUq8kD6W4Fj9PYO+lp05GhIaPp89mtUWY0k8N2EEo6YvJc58eONjzP60hiK/PoRab/lLodXbi6z2fcounmLt2LVVir2kRcnMsRJ7Nwlq3YHnf36ERx+1L74LM0/wxoPref3NX8gp9Uym6/8yhtzjFtu2JVvH8vs3llmroaO+oFO8PcFVwPGFtlu5kc8uIMoJ4SS6YwA9Jz9uM563aiIXbZLzXKP80BouWCVeNB2S4JhgcbSWbJ1goOD4z5X/jJrNXTWUgBG1eJC72kUAoDn8i8sdPN0q+EzXTlCaNpL8oU+gs5e1qBqF4os/UNxX09ZeIwKnriVsw7IqCzAbNsyk8L52FC7fgu5adTlmArVCXb17yv/pTSiH2n//tKsmW/VKBtGYD1wqqSK+bw5BI2OsRk9SNmqJHS+wk2h+odi6+4tqCoEO1scz/r7Xhw2MZ/nxzUdIXmaZEZG86nX6hgGN+rJx3WiLY8tS7mT9Ycs+pgKeQZuXw7ZXP+FfD+8m64SdCcpmPL1lPCMTawrkUnDfcyOY/14PqsoXPPXxQeb9bS2vv/kLZ/N8JzGl3qOpPho1cPB6egywvzWbs2kKl61Ek+T+NS6VVAnuOZu7E6zt/2l+//dS921saH/h8FuW5WCQT6CVg/XxNKd+shG5vmOfNZRezgNA1rWjA15WMeE9kir/qdW6/He4RfCZrp2gdPF4rg8cjCbDfgcN8YQ1qL5NQxrl+C6yf4chhB06QvD0UVXOMWyYSfHAjuTPWYL6+IX/YU+Le9D/dqTKY37Jy1COtx84avhhvm33lOjphLoh3k4+8z0CrEsv5a+kePlPLp8bSimbZp2MApKXHnGw24sG9ftWYtFtrdh8GQ27Fg8lcapV7Za4NJZP6nrrYezYJSxKspwyLv5+Nh0TRJ+n0OblsO21T5n64Bds325fMNw5tg9v7BhEbJTjPY1UHeKY8/PjTHy26pp8pz4+yKIH1/PyS7vIOn7dQ9Xt/nco/rPq9HLRPa+RkGLfHpfuW8AxK08gqmfo4YZ4u+YTVxNhXWpAvYYD691jj08utE5GAdUTj+BY9KuGC1utxGKzKB+qfam/vcXs4H2RsfymrXTVv+ei4Ks4+RMlc0ZWCr3NVTSPVw0nKP0IyslJTl4sGNnoNMJ3bkeWXHXjcuPXKykb05fr8X+neO0WtGeuCeKvthRmUbbwK/vHOryIMnWIXSFjPL6BQpu4vXiC1z7tphZ5d6DYsNLm2sYNT1BywDXhoF37nEV3DwBUUwh2KEZQg2bVFJvn+7dv2aAFn6HgGIuHyuk3y7pQXxI7dswm2mKsETM378RS82XzWJyK6et/FLJp3Uj+yVNsfumTSqG3pYrvhbIJ4z96nOcntXOu8wMyuo4axIodQxg8uOp0mtydp1n71Bae7rWRtet+4fczJYL4qy1FWfyW/p39Y1EzSHhmsN3fVN3JD8m0idvrRIeXpzgommoiis7zltlcW//9BI4ddc0e56RPs+juAYB8Au0dihHUcHnTMzbPD2wd7UOCLwxlu0oPqebHrxzwihZwcWflZ0DU7E6XewjX+nUwlV5Bu+dL1O8tpMJe5q0ZAXM3oRja3S0/fn7KtgSnbiZwXBalS/4fuj3WJVxuchLdipnoVgBEIk7+B5KEewlo2wr/RmGIfCpdx7fQffFGFUZ5OCGrn7Ir3kwnt1AwJs1mXPr+KmRK963NL2oAIXOHU2RV2087+V9If1pLgBOx9NqNz1CywvZGRb7Cspez6cwn5Ke8hSixN6KoJohCwHT1DIaMr+y62CXd76z9YuxgKnG2AaeHMBSwa+Nr9BtnLxs3iYzfMxh4h53vV6O+/N+hdajix1kMLxuXyLKlE8lY9zIPdfW97HvrNASpxPdsR0VpIUd/PM5Xa3/jgr3MWzO6v9ifx5JbuaXOor8yigdfeoS+T5zls2U/sTezqvhGNVmrD5K1+iAg4c7BLejSsxUxbSNQNQokSObtrun1h/zdS208XZU8yD3/7ym74s1w5jP2zLf9fjaduZKmtUkwrwFR4wHcM+pBsqxq++UsfYGod98jwokPWe7W5zi2PdNmvOUL/7T4Ww0XNvN96gpk7XohUzVBGgz6/LMUHbTfwSsizj32WF/mHnscFt8XMk+D+kOObR9ebau60r3LyLkRH6no0s7lLVmHLJip9Aq6Q/vQbt2Mbo/9LVtzRMmpKGaMQeKBIrmi5t0JWfolxpM/UbpkJroDudXMzsWQsRJDxkrUgGjkSsJmDqgD78sFm/puvkjA6I9Q6CZaiaAYgr6Yb1dQGY9/QsGYl2w8qeIXt9vP4HURydBU5F9tsfKo7aF49hbCl1bf09eSUsoXP0n5ZtvPsvjF7QTFWP6xfq37IYl+Cd2eLTV7KVRTkMc4rj5NGgN+VjchptJr6PZ8SIm9upV1geYaP25Zx8uPzbJfay9uNoe+n0/Xat7ysK5juboPGve0FH1kryY5fjVxo9NYOvNJ+sY6LvxO79rEdxcgqkkTIhsrCQyUAIGEyN0gzCSBFJ+1vKM9f/Yc18JDcL0bngG1upzyonIKC3K5cD4HVcJwHop1LLZKW1rImcNn+TnjBFmZNftIIwfH8tS0njT3gD0Oat6K0W+04qGTp/h02V6yfqnuxdFzavtpTm2vTB5RDk9g3gsd6qDQ93V+/K/vhxSohn5IrH6ylQhqQ9vF/0Fl50XTnNzM3vnzbG5CFSmf2c/gdRHlgLm0/HmblUctk8NLP6Pvi8Nq4U0q5ezqCfyZedTmiCLlM2KsOiyJW/SlkWoeuX9sq0IQmyGfQItadGgyag2IpJYrN5Rd41rWRo59b7s+ZwiMf4QI+Rry1JWt6g5K/kvXAR1txFz+3qUcfO9mF5X+tElwveOGn8lUdf0Cww8rKH51E8b86kSVGR1GEfT/piNv7b3OGBVnfqLsrf9U4/EDiET+/laCOru7/58B3db1aPKDkbRpjig0FFFICH5yMX5iCSZNMRUXf0fz+jT0NjXsDnhEFLkDzfKRlN4QG9K3fkZhJ+lC/90SimbZZmH7Ja9ElepBUV2YRX4/20xgR19PU04WxU+Psnk/APweWIZqvv1ta136MxRXtd19i+Eodi5GqqxxGQAYvkulcFZl3Uk/VQx+CqDkJEa7GW/xKH7Y7FS2swWawzwuj7/dMSJpFfm7JmH7ymm48sdRvklfy7jU1TZHbz19djr/N3+EnedXcfnzu5jQsl/VHSuSJrJu2ngGJMVzh6K6n4wC3uyrYmpN1Z7rCUmL9rFrZo9q51zds4clC85QWOig4mzbjPGpiXRv7b3OGPlnTvHlin3VePwAJAx95x8M7OzufrkV/Jmxj/35Ulq3URIWIiM4RI5U7o9Y4o9Breb6pb/4Ycl+jlh5Q5PeGcXIzr7ZQeTy+kc5fkNsRD37A7F2ki4K9y4l6701NuOie5bR9xkPNi0oymLPVNtM4KiZPxHrgMg0XM3iyMKx5NuxeaK417h/xmC7wjF/+3McrGq7+xYP0mn5IiId9GyW7n2ZzBsCSyRvg78cUJ/GfnJ+J2JXfOxUtjNUbrt/b+6JVT1I64cfoXHrcHQXD3Hu03+Tb5Zw03TmT24R7dWKcHGPYUj7bEedUYPgUw1EPn8mQd3c1/PNUfxb9670+F38hbJ1b6HNsPWkSd//giCPiCsxlGaiW7GnluGUkfiHe7o5uPPIpq5C/0M39EPSbcWe5gpli5+y0xUF6PAiYZ4UewDK7oQsGnVLKAEQPR5pTT0QDddQb3iNshXW7d5unmM6yirEHoAkvi9QteDzH/kqihmP1Kr3s/jehxGzCQNgyj+JqdrSBm0ReaIEnEXrMgPHvtrI1j0/8+mC1VTfjSyO5Tu38FxfR4tpVyKL7suH6lN0m3AnU+2pvt2rGbe7UmAmJU9kYN9e9H90NF0bWb+wYkIaUKuHEFnNdewad4/jb70vkL69BsGnbETKK33od0/1/VE8gar1nYx+406GXbzA1x9k8c12W0/agHdSGOgRceUPZTnsXV3A3lo9T0KTcN+tr9h07Erys3tT0OsjW7GnzeHkmomcO2in5E7UDO71pNgDCO1O16dSbgklAFSPE9W0Znt88bPX+X27dbu3m+d4hoQqxB6AMjYJqhF8gQkv03n8SIJrYY+Du6WgeC+dEsCoPo2x2ipMMchdcE0HxDxOYqqKrLQXKsVy/jbOrNrGGZuZETR9drPbPLTVevhuolk1ntI1drYkVYnIX5pF4H1tfSZI3VR4Ac0XG1EvXYsRED29FdV414oVVovhBIXWHSFqInFxLbcg6wIDtvcDBZT8rRtae8JENZ7QHXPwTphTKWWTO6M+AOKnPyB0fO9qX0vTmS1cT5lZ9QTVKEJ3pFW/dsMJCnoMrtzSVcUg6tgRcWxXJF27IG3nvBhTL/47ZZur805XIp67HeXQqmM9HMaOh69416Rb3SzO71pMy36zqj1F3MTlbF74HO1cskEGDm9KJf6x6rpzABPXcXnFWGxDA0t4s1MIU93RI9cHiFu0j6M1ePhucvjdT1m93s6WpDKMobN787fEKDclS7lOReF19n95mM/fOkchEDlxEPPGVZ3l6zKGHF7v84WdQtHVkHAPy9/o4ls9pG2wb4+P/bM3OfaEifxxur81G6WX7PHJed05dxYUg9fQLaV3tZ4kw4XP2JX676onyFPo/ta86tduOMHep4ZVbunK2yCLbk9om66oOnSmUZu2yJx8My+ufrD6/rY3UIz6jF4D3GCPDQVc/no9p79Yg8bsfRSpEmiU+DBtBg0g2I0fTIcEH2gon9OP8q9vePqiByJ//lkCE3xH6NlSiv74Ofw72O6NuxtHf7QB/B5IJXT+GB/KGqotGnQ//JfSGWlm26oDCfnhbee6UjhL4Wm0V0OQxjiyTa9Bn/lfSp5Ns02yUI0ndNscJA4INpNGA2IxfrVx49WA8cAS8ifbL1Beub54pNPnovi7m25aNMd4XB53W/Alr6J46ySL9mXnP59Dy2R7QiyZj/YsZ1SfaDvHnFzOlf28NqUnqdYJvwAT01G/O6LKzhxXju0i8yw0j1QSGhqKPEROoKR+dHzQ68tRq9WUFxVx+VIuYR2S6NHGUa+/nh9e+oiPd97w9DVrxNAZPUjqFeXDokXDxeN5hHZo5vEevFmvbWTtFseKZMv6xTLn1Z440FLWR9GQvy+do6sWmCUs9KfrijeJ8OYOddEZcq4riGrtmD0uPJTOL28tsE2ykD9O92WzUTrwQTZqNRj9xYjdaI81R5eyZ6nt1vjt9XUi6uF/E5vkfieSoagAXYUBcVAYAVLPKAQHBR9gOE3J/Az8HxqBvHMLHxZ63sd4YAX5k5dWeVzUbTiSfv2R3ptAQJQ3VZEHKT1B8ZjB6M4noti51uG4tTql9FeKhg1Ff8ND6ZeYinLpmLr1hhT+RH6/J24I0UhE3brg3/puxB07I+nSnoAo94YiGM5/iqRlitnIbM6Z5luVUtHw6SQ5KbdC95JZnpHKuIe61r6vrWOr4vSujfyr3zhu675pnNIvpU39vTPyLIarbFn4K+FDOnFv53Cf8ej5AsUH9zDzWXuVpitRdmlCl76t6d67Da2ifHcrt1aUneDw3GHk5ScQu/w9otyYkesxyn7l4PMPk39Dm4vazSbhxcfdVDrGSYp+YvfUCTeEaASyVp0JjGpHyF2diOjQHlVj34y7dxTHBZ9A1WhOU/puBqbwOxCpghEFBCGKaIR/ZCSiRo0QNdQfLUMpFZpg/OuThi39lcJhkxA9/TaKoV184MbFgLGwBMRyRMFe+PEpOc2nm76jVHrjFjqgDf8Y1cdWyF37kUkTtnDfvybxYJ92HhJ6Novj2K7/Y/H0pdy7+nsm9ajfxlWgjtBcZdvqX9FHhBAaFoBcEoAiIpiIyFBCGikIasD2uFwbTKBv5p7Yp+xX9j8/Bcmw5XQe0MXju3E1Y0BXVIJRLEcW1EBuBswQBJ+AgICAgICAQAOn7gW1gICAgICAgICARxEEn4CAgICAgIBAA0cQfAICAgICAgICDRxB8AkICAgICAgINHAEwScgICAgICAg0MARBJ+AgICAgICAQANHEHwCAgICAgICAg0cQfAJCAgICAgICDRwBMEnICAgICAgINDAEQSfgICAgICAgEAD5/8DVO5vYuFD8UYAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=636x86 at 0xB2774EC88>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "img = Image.open('./test_image.png')\n",
    "img"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<PIL.Image.Image image mode=L size=236x32 at 0xB2774EF98>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "img = img.convert('L')\n",
    "scale = img.size[1] * 1.0 / 32\n",
    "w = img.size[0] / scale\n",
    "w = int(w)\n",
    "img = img.resize((w, 32))\n",
    "img"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4. 将测试图片传入模型进行字符预测，获得预测结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[7.32723276e-14, 5.90867133e-09, 3.72121564e-14, ...,\n",
       "         2.45357519e-11, 4.12480716e-09, 5.87536611e-15],\n",
       "        [5.70836645e-14, 7.45682893e-09, 3.29477554e-14, ...,\n",
       "         2.23865336e-11, 3.23749738e-09, 3.16329502e-14],\n",
       "        [6.08330254e-14, 1.10404965e-08, 8.85024137e-14, ...,\n",
       "         4.48241409e-11, 1.15610312e-08, 3.29465136e-11],\n",
       "        ...,\n",
       "        [2.34782913e-18, 5.73790634e-20, 1.56465448e-17, ...,\n",
       "         1.57386582e-19, 4.74277041e-15, 9.99999881e-01],\n",
       "        [1.45687196e-18, 5.85361873e-21, 2.30722645e-19, ...,\n",
       "         3.51459551e-21, 9.96941474e-16, 1.00000000e+00],\n",
       "        [9.89614003e-15, 1.16845672e-18, 3.03500541e-17, ...,\n",
       "         4.78296872e-19, 4.07981508e-15, 1.00000000e+00]]], dtype=float32)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "img = np.array(img).astype(np.float32) / 255.0\n",
    "X = img.reshape((32, w, 1))\n",
    "X = np.array([X])\n",
    "y_pred = basemodel.predict(X)\n",
    "y_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = y_pred[:, 2:, :]\n",
    "out = decode(y_pred)\n",
    "\n",
    "if len(out) > 0:\n",
    "    while out[0] == u'。':\n",
    "        if len(out) > 1:\n",
    "            out = out[1:]\n",
    "        else:\n",
    "            break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "预测结果为：\"文字识别模型文字识别。\"\n"
     ]
    }
   ],
   "source": [
    "print(\"预测结果为：\\\"\"+out+\"\\\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
